package io.renren.modules.seal.service.impl;

import cfca.paperless.ClientConstants;
import cfca.paperless.base.BaseConstants;
import cfca.paperless.base.util.Base64;
import cfca.paperless.base.util.IoUtil;
import cfca.paperless.base.util.PwdEncryptUtil;
import cfca.paperless.client.PaperlessClient;
import cfca.paperless.dto.RequestHead;
import cfca.paperless.dto.ResponseDto;
import cfca.paperless.dto.ResponseHead;
import cfca.paperless.dto.bean.SealStrategy;
import cfca.paperless.dto.request.requestbody.tx40.SealPdfRequestBody;
import cfca.paperless.dto.request.tx40.SealPdfRequest;
import cfca.paperless.dto.response.responsebody.tx40.SealPdfResponseBody;
import cfca.paperless.dto.response.tx40.SealPdfResponse;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.util.FileUtils;
import io.renren.common.utils.Constants;
import io.renren.common.utils.Result;
import io.renren.modules.api.dto.AddSealCustNo;
import io.renren.modules.api.dto.AddSealDto;
import io.renren.modules.seal.entity.EcifSealFileEntity;
import io.renren.modules.seal.entity.EcifTemplateConfigEntity;
import io.renren.modules.seal.service.EcifSealFileService;
import io.renren.modules.seal.service.EcifTemplateConfigService;
import io.renren.modules.seal.service.SealApiService;
import io.renren.modules.seal.utils.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @auther xiegaolong
 * @description
 * @date 2024/11/11
 */
@Slf4j
@Service
public class SealApiServiceImpl implements SealApiService {

    @Resource
    private EcifTemplateConfigService templateConfigService;

    @Resource
    private EcifSealFileService sealFileService;

    @Override
    public Result addSeal(AddSealDto dto) {

        log.info("文档盖章接口,dto:{}", JSONUtil.toJsonStr(dto));
        try {
            Result result = checkDto(dto);
            if (!result.isSuccess()){
                return result;
            }
            //从电子档案系统下载文件
            byte[] fileContext = getFileContext(dto);
            if (fileContext == null){
                log.info("从电子档案下载文件不成功，请检查参数是否正确");
                return Result.errorMsg("从电子档案下载文件不成功，请检查参数是否正确");
            }

            PaperlessClient paperlessClient = PaperlessClientFactory.getPaperlessClient();
            RequestHead requestHead = PaperlessClientFactory.getHead(dto.getTransNo());
            SealPdfRequest sealPdfRequest = new SealPdfRequest();
            sealPdfRequest.setHead(requestHead);

            SealPdfRequestBody requestBody = new SealPdfRequestBody();
            requestBody.setInputSource("");
            requestBody.setInputType("2");
            requestBody.setPdfData(fileContext);
            requestBody.setOutputFilepath("");
            requestBody.setTimestampChannel("0");

            //支持盖多个章
            byte[] pdf = null;
            //获取盖章信息
            List<SealStrategy>  sealStrategyList = new ArrayList<>();
            List<AddSealCustNo> custNoList = dto.getCustNoList();
            for(AddSealCustNo tmpDto: custNoList){
                Map<String, Object> sealStrategyMap = getSealStrategy(dto, tmpDto);
                if (!(Boolean) sealStrategyMap.get("flag")){
                    return Result.errorMsg(sealStrategyMap.get("message"));
                }
                sealStrategyList.add((SealStrategy)sealStrategyMap.get("sealStrategy"));
            }


            for(SealStrategy sealStrategy: sealStrategyList){
                requestBody.setSealStrategy(sealStrategy);
                sealPdfRequest.setBody(requestBody);

                /************请求签章**************/
                ResponseDto responseDto = paperlessClient.execute(sealPdfRequest);
                SealPdfResponse sealPdfResponse = (SealPdfResponse)responseDto;
                ResponseHead responseHead = sealPdfResponse.getHead();
                log.info("响应结果:{}",JSONUtil.toJsonStr(responseHead));
                SealPdfResponseBody responseBody = sealPdfResponse.getBody();

                if (ClientConstants.CODE_SUCCESS.equals(responseHead.getCode())){
                    pdf = responseBody.getPdf();
                    requestBody.setPdfData(pdf);
                }else{
                    return Result.errorMsg(JSONUtil.toJsonStr(responseHead));
                }
            }
            if (pdf != null){
                String fileOutPath = PaperlessConfig.tempOut+"/"+dto.getFilename();
                log.info("fileOutPath:"+fileOutPath);
                IoUtil.write(fileOutPath, pdf);

                Map<String,String> map = new HashMap<>();
                map.put("transNo",dto.getTransNo());
                if ("Xd".equals(dto.getSystemCode())){
                    EapFile eapFile = EAPUtils.uploadFile(dto.getFilename(), pdf);
                    log.info("盖章完成，上传到信贷电子档案系统:{}",JSONUtil.toJsonStr(eapFile));
                    map.put("busiid",eapFile.getBusiid());
                    map.put("filename",eapFile.getFilename());
                }else if ("Hx".equals(dto.getSystemCode())){
                    EapFile eapFile = HXEAPUtils.uploadFile(dto.getFilename(), pdf);
                    log.info("盖章完成，上传到核心电子档案系统:{}",JSONUtil.toJsonStr(eapFile));
                    map.put("busiid",eapFile.getBusiid());
                    map.put("filename",eapFile.getFilename());
                }

                return Result.success(map);

            }

        } catch (Exception e) {
            e.printStackTrace();
            return Result.errorMsg(e.getMessage());
        }

        return Result.success("");
    }





    private Map<String,Object> getSealStrategy(AddSealDto sealDto,AddSealCustNo dto){

        Map<String,Object> map = new HashMap<>();
        map.put("flag",true);
        map.put("message","");
        map.put("sealStrategy",null);

        SealStrategy  sealStrategy = new SealStrategy();

        try {
            String type = BaseConstants.SEAL_TYPE_IMAGE;
            String sealCode = dto.getCustNo();
            sealCode = Constants.isKj ? "Kj"+sealCode:"Sy"+sealCode;

            String sealPassword = PwdEncryptUtil.encrypto(PaperlessConfig.sealPassword);
            sealStrategy.setSealInfo(type, sealCode, sealPassword);

            /**
             * 客户号类型 0：普通客户号  1：结算中心客户号
             */
            String custType = dto.getCustType();

            String custNo = dto.getCustNo();

            String pngFilePath = "";
            if ("0".equals(custType)){
                pngFilePath = PaperlessConfig.sealOutPut+"/"+custNo+".png";
            }else{
                pngFilePath = PaperlessConfig.jszxOut+"/"+custNo+".png";
            }
            if (!new File(pngFilePath).exists()){
                log.info("印章证书未找到，请先制作好客户号印章图片:{}",custNo);
                map.put("flag",false);
                map.put("message","印章证书未找到，请先制作好客户号印章图片:"+custNo);
                return map;
            }



            /**
             * 客户号类型 0：普通客户号  1：结算中心客户号
             */
           /* String custType = dto.getCustType();

            String custNo = dto.getCustNo();

            EcifSealFileEntity sealFile = sealFileService.findByCifseqAndCustType(custNo, custType);

            if (sealFile == null){
                log.info("印章证书未找到，请先制作好客户号印章图片:{},cusType:{}",custNo,custType);
                map.put("flag",false);
                map.put("message","印章证书未找到，请先制作好客户号印章图片:"+custNo);
            }
            //从eap电子档案下载印章图片
            EapFile eapFile = new EapFile();
            eapFile.setBusiid(sealFile.getBusiid());
            eapFile.setFilename(sealFile.getFilename());
            String filePath = EAPUtils.downloadFile(eapFile);
            //外传图片
            byte[] imageData = EAPUtils.file2Byte(new File(filePath));
              */

            byte[] imageData = FileUtils.readFileToByteArray(new File(pngFilePath));
            //对图片进行扣白底
            //imageData = ImageUtil.transferAlpha(imageData);



            //图片进行Base64编码/
            String imageDataString =  new String(Base64.encode(imageData), PaperlessConfig.DEFAULT_CHARSET);
            sealStrategy.setSealImage(imageDataString);

            //算法，非空
            String hashAlg = BaseConstants.HASHALG_SM3;
            sealStrategy.setHashAlg(hashAlg);
            //透明度，0-1.0f，默认1.0f,不透明
            sealStrategy.setFillOpacity("1");
            //是否显示，默认1 显示
            sealStrategy.setVisible("1");


            // 签章杂项信息
            //签章人姓名，必填
            String sealPerson = sealDto.getSignUser();
            //签章地点，可以为空
            String sealLocation = "";
            //签章原因，可以为空
            String sealReason = sealDto.getSealReason();
            sealStrategy.setSealMiscInfo(sealPerson, sealLocation, sealReason);


            EcifTemplateConfigEntity templateConfig = templateConfigService.findByTemplateCodeAndConfigKey(sealDto.getTemplateCode(), dto.getConfigKey());
            if (templateConfig == null){
                map.put("flag",false);
                map.put("message","未配置好模板参数，请先配置模板参数,TemplateCode:"+sealDto.getTemplateCode()+",ConfigKey:"+dto.getConfigKey());
                return map;
            }
            //绝对定位
            if ("0".equals(templateConfig.getConfigType())){
                sealStrategy.setSignWithCoordinate(templateConfig.getPageNo(), templateConfig.getLx(), templateConfig.getLy());
            } else if ("1".equals(templateConfig.getConfigType())) {
                sealStrategy.setSignWithKeywordInfo(templateConfig.getKeyword(),templateConfig.getOffsetX(),templateConfig.getOffsetY());
            }
        } catch (Exception e) {
            e.printStackTrace();
            map.put("flag",false);
            map.put("message",e.getMessage());
            return map;
        }

        map.put("flag",true);
        map.put("message","success");
        map.put("sealStrategy",sealStrategy);
        return map;
    }


    private byte[] getFileContext(AddSealDto dto){
        EapFile eapFile = new EapFile();
        eapFile.setBusiid(dto.getBusiid());
        eapFile.setFilename(dto.getFilename());
        //信贷系统
        if ("Xd".equals(dto.getSystemCode())){
            String filePath = EAPUtils.downloadFile(eapFile);
            if (StringUtils.isNotEmpty(filePath)){
                return EAPUtils.file2Byte(new File(filePath));
            }
        }else if ("Hx".equals(dto.getSystemCode())){
            String filePath = HXEAPUtils.downloadFile(eapFile);
            if (StringUtils.isNotEmpty(filePath)){
                return EAPUtils.file2Byte(new File(filePath));
            }
        }
        return null;
    }

    private Result checkDto(AddSealDto dto){
        if(StringUtils.isEmpty(dto.getTransNo())){
            return Result.errorMsg("业务系统流水号不能为空");
        }
        if(StringUtils.isEmpty(dto.getBusiid())){
            return Result.errorMsg("电子档案id不能为空");
        }
        if(StringUtils.isEmpty(dto.getFilename())){
            return Result.errorMsg("电子档案名称不能为空");
        }
        if(StringUtils.isEmpty(dto.getSystemCode())){
            return Result.errorMsg("业务系统代码不能为空");
        }
        if(StringUtils.isEmpty(dto.getTemplateCode())){
            return Result.errorMsg("模板id不能为空");
        }
        if(StringUtils.isEmpty(dto.getSignUser())){
            return Result.errorMsg("签章人姓名不能为空");
        }
        if(CollectionUtils.isEmpty(dto.getCustNoList())){
            return Result.errorMsg("盖章客户号不能为空");
        }
        if (StringUtils.isEmpty(dto.getSignUser())){
            return Result.errorMsg("签章人不能为空");
        }
        return Result.success("");
    }
}
